﻿using System;
using dnAnalytics.Mcmc;
using dnAnalytics.Statistics.Distributions;
using NUnit.Framework;

namespace dnAnalytics.Tests.MCMC
{
    [TestFixture]
    public class RejectionSamplerTests
    {
        [Test]
        public void RejectTest()
        {
            var uniform = new ContinuousUniform(0.0, 1.0);
            uniform.RandomNumberGenerator = new dnAnalytics.Random.MersenneTwister();

            var rs = new RejectionSampler<double>(x => System.Math.Pow(x, 1.7) * System.Math.Pow(1.0 - x, 5.3),
                                                  x => 0.021,
                                                  uniform.Sample);
            Assert.IsNotNull(rs.RandomNumberGenerator);

            rs.RandomNumberGenerator = uniform.RandomNumberGenerator;
            Assert.IsNotNull(rs.RandomNumberGenerator);
        }

        [Test]
        public void SampleTest()
        {
            var uniform = new ContinuousUniform(0.0, 1.0);
            uniform.RandomNumberGenerator = new dnAnalytics.Random.MersenneTwister();

            var rs = new RejectionSampler<double>(x => System.Math.Pow(x, 1.7) * System.Math.Pow(1.0 - x, 5.3),
                                                  x => 0.021,
                                                  uniform.Sample);
            rs.RandomNumberGenerator = uniform.RandomNumberGenerator;

            double sample = rs.Sample();
        }

        [Test]
        public void SampleArrayTest()
        {
            var uniform = new ContinuousUniform(0.0, 1.0);
            uniform.RandomNumberGenerator = new dnAnalytics.Random.MersenneTwister();

            var rs = new RejectionSampler<double>(x => System.Math.Pow(x, 1.7) * System.Math.Pow(1.0 - x, 5.3),
                                                  x => 0.021,
                                                  uniform.Sample);
            rs.RandomNumberGenerator = uniform.RandomNumberGenerator;

            double[] sample = rs.Sample(5);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void NoUpperBound()
        {
            var uniform = new ContinuousUniform(0.0, 1.0);
            uniform.RandomNumberGenerator = new dnAnalytics.Random.MersenneTwister();

            var rs = new RejectionSampler<double>(x => System.Math.Pow(x, 1.7) * System.Math.Pow(1.0 - x, 5.3),
                                                  x => System.Double.NegativeInfinity,
                                                  uniform.Sample);
            double s = rs.Sample();
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullRandomNumberGenerator()
        {
            var uniform = new ContinuousUniform(0.0, 1.0);
            uniform.RandomNumberGenerator = new dnAnalytics.Random.MersenneTwister();

            var rs = new RejectionSampler<double>(x => System.Math.Pow(x, 1.7) * System.Math.Pow(1.0 - x, 5.3),
                                                  x => System.Double.NegativeInfinity,
                                                  uniform.Sample);
            rs.RandomNumberGenerator = null;
        }
    }
}
